interface Fish {
  swim: () => void
}

interface Bird {
  fly: () => void
}

let pet: Fish = {
  swim() {
    console.log('swim');

  }
}

function isFish(pet: Fish | Bird): pet is Fish {
  return (pet as Fish).swim !== undefined;
}

console.log(isFish(pet));


type Point = { x: number; y: number };
type P = keyof Point;
let o: P = 'y'

type Arrayish = { [n: number]: unknown };
type A = keyof Arrayish;
let num: A = 1

type Mapish = { [k: string]: boolean };
type M = keyof Mapish;
let count: M = '2'


type Todo = {
  id: number;
  text: string;
  done: boolean;
}

const todo: Todo = {
  id: 1,
  text: "Learn TypeScript keyof",
  done: false
}
// extends 关键字约束 K 类型必须为 keyof T 联合类型的子类型。 'id' | 'text' | 'done'
function prop<T extends object, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

const id = prop(todo, "id"); // const id: number
const text = prop(todo, "text"); // const text: string
const done = prop(todo, "done"); // const done: boolean

console.log(id, text, done);


function toArray(x: number): Array<number> {
  return [x];
}


interface UserItem {
  name: string
  age: number
  enjoyFoods: string[]
  friendList?: UserItem[]
}

let obj: UserItem = {
  name: 'jack',
  age: 12,
  enjoyFoods: ['西瓜'],
  friendList: [
    {
      name: 'jack',
      age: 12,
      enjoyFoods: ['西瓜']
    }
  ]
}

class C {
  x = 0;
}


type AA = typeof C
type T0 = InstanceType<typeof C>;         // C
type T1 = InstanceType<new () => object>; // object
type T2 = InstanceType<any>;              // any
type T3 = InstanceType<never>;            // any
// type T4 = InstanceType<string>;           // 编译错误
// type T5 = InstanceType<Function>;         // 编译错误


interface PageInfo {
  title: string;
}
type Page = "home" | "about" | "contact";

type xxx = Record<Page, PageInfo>

let obj1: xxx = {
  home: {title: 'aa'},
  about: {title: 'haah'},
  contact: {title: 'aaa'}
}

export { }

